package com.bitrate.dagger.redis.config;

import org.redisson.Redisson;
import org.redisson.api.RedissonClient;
import org.redisson.client.codec.Codec;
import org.redisson.config.Config;
import org.redisson.config.SingleServerConfig;
import org.redisson.config.SslProvider;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import com.bitrate.dagger.redis.aspect.RateLimitAop;
import com.bitrate.dagger.redis.aspect.RedisLockAop;


@Configuration
@EnableConfigurationProperties(value = RedissonProperties.class)
@ConditionalOnClass(RedissonProperties.class)
public class RedissonConfig {

	@Autowired
	private RedissonProperties redissonProperties;

	@Bean
	@ConditionalOnMissingBean(RedisLockAop.class)
	public RedisLockAop redisLockAop() {
		return new RedisLockAop();
	}

	@Bean
	@ConditionalOnMissingBean(RateLimitAop.class)
	public RateLimitAop rateLimitAop() {
		return new RateLimitAop();
	}

	@Bean
	@ConditionalOnMissingBean(RedissonClient.class)
	public RedissonClient redissonClient() {
		Config config = new Config();
		try {
			config.setCodec((Codec) Class.forName(redissonProperties.getCodec()).newInstance());
		} catch (Exception e) {
			throw new RuntimeException(e);
		}
		config.setTransportMode(redissonProperties.getTransportMode());
		if (redissonProperties.getThreads() != null) {
			config.setThreads(redissonProperties.getThreads());
		}
		if (redissonProperties.getNettyThreads() != null) {
			config.setNettyThreads(redissonProperties.getNettyThreads());
		}
		config.setReferenceEnabled(redissonProperties.getReferenceEnabled());
		config.setLockWatchdogTimeout(redissonProperties.getLockWatchdogTimeout());
		config.setKeepPubSubOrder(redissonProperties.getKeepPubSubOrder());
		config.setUseScriptCache(redissonProperties.getUseScriptCache());
		config.setMinCleanUpDelay(redissonProperties.getMinCleanUpDelay());
		config.setMaxCleanUpDelay(redissonProperties.getMaxCleanUpDelay());
		String redisAddress = "redis://" + redissonProperties.getHost() + ":" + redissonProperties.getPort();
		System.out.println(redisAddress);
		switch (redissonProperties.getModel()) {
		case SINGLE:
			SingleServerConfig singleServerConfig = config.useSingleServer();
			singleServerConfig.setAddress(redisAddress);
			singleServerConfig.setConnectionMinimumIdleSize(redissonProperties.getConnectionMinimumIdleSize());
			singleServerConfig.setConnectionPoolSize(redissonProperties.getConnectionPoolSize());
			singleServerConfig.setDatabase(redissonProperties.getLockIndex() != null ? redissonProperties.getLockIndex() : 0);
			singleServerConfig.setDnsMonitoringInterval(redissonProperties.getDnsMonitoringInterval());
			singleServerConfig.setSubscriptionConnectionMinimumIdleSize(redissonProperties.getSubscriptionConnectionMinimumIdleSize());
			singleServerConfig.setSubscriptionConnectionPoolSize(redissonProperties.getSubscriptionConnectionPoolSize());
			singleServerConfig.setClientName(redissonProperties.getClientName());
			singleServerConfig.setConnectTimeout(redissonProperties.getConnectTimeout());
			singleServerConfig.setIdleConnectionTimeout(redissonProperties.getIdleConnectionTimeout());
			singleServerConfig.setKeepAlive(redissonProperties.getKeepAlive());
			singleServerConfig.setPassword(redissonProperties.getPassword());
			singleServerConfig.setPingConnectionInterval(redissonProperties.getPingConnectionInterval());
			singleServerConfig.setRetryAttempts(redissonProperties.getRetryAttempts());
			singleServerConfig.setRetryInterval(redissonProperties.getRetryInterval());
			singleServerConfig.setSslEnableEndpointIdentification(redissonProperties.getSslEnableEndpointIdentification());
			singleServerConfig.setSslKeystorePassword(redissonProperties.getSslKeystorePassword());
			singleServerConfig.setSslProvider(SslProvider.JDK);
			singleServerConfig.setSslTruststorePassword(redissonProperties.getSslTruststorePassword());
			singleServerConfig.setSubscriptionsPerConnection(redissonProperties.getSubscriptionsPerConnection());
			singleServerConfig.setTcpNoDelay(redissonProperties.getTcpNoDelay());
			singleServerConfig.setTimeout(redissonProperties.getTimeout());
			break;
		default:
			break;

		}
		return Redisson.create(config);
	}
}
